﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TheatreManagementSystem;

namespace TicketingSystemUserInterface
{
    public class Interface
    {
        static MainTheatreSystem ourSystem;
        public static void Main(string[] args)
        {
            int choice = -1;
            ourSystem = new MainTheatreSystem();
            while (choice != 0)
            {
               // SetWindowSize(75);

                string[] massages = {
               "Please, state what you'd like to do:",
               "1. Create a new ticket. Press 1.",
               "2. Create a new customer account. Press 2.",
               "3. Create a new theatre hall. Press 3.",
               "4. Create a new performance. Press 4.",
               "5. Create a new seller account. Press 5.",
               "6. Find all sold tickets by a customer, Press 6",
               "7. Find all sold tickets by a seller, Press 7",
               "8. Check the empty seat in the teathre.Press 8",
               "Or press Enter to exit the aplication",

                              };
                PrintTheMainMenu(massages);


                Int32.TryParse(Console.ReadLine(), out choice);

                switch (choice)
                {
                    case 1: CreateNewTicket(); break;
                    case 2: CreateNewCustomerAccount(); break;
                    case 3: CreateNewHall(); break;
                    case 4: CreateNewPerformance(); break;
                    case 5: CreateNewSeller(); break;
                    case 6: FindAllTicketsByCustomer(); break;
                    case 7: FindAllTikecketsBySeller(); break;
                    case 8: PrintTheHallViewOfPerpormance(); break;
                    default:
                        break;
                }
            }
        }
        //private static void SetWindowSize(int resize)
        //{
        //    int bufferWidth = Console.BufferWidth;
        //    bufferWidth += resize;
        //    Console.BufferWidth = bufferWidth;
        //    Console.WindowWidth = bufferWidth;
        //}//sometimes thows exception

        private static void PrintTheMainMenu(string[] massages)
        {
            Console.BackgroundColor = ConsoleColor.DarkBlue;
            int longestMessage = FindLongestMassage(massages) + 4;
            int lineLength = massages.Length + 4;
            for (int i = 0, index = 0; i < lineLength; i++)
            {
                if (i == 0)
                {
                    Console.WriteLine(new string('*', longestMessage));
                }
                if (i == 0)
                {
                    Console.WriteLine(new string('*', 1) + new string(' ', longestMessage - 2) + new string('*', 1));
                }
                else
                {
                    Console.WriteLine((new string('*', 1) + new string(' ', 1) + massages[index]).PadRight(longestMessage - 2) + new string(' ', 1) + new string('*', 1));
                    index++;
                    if (index == massages.Length)
                    {
                        Console.WriteLine(new string('*', 1) + new string(' ', longestMessage - 2) + new string('*', 1));
                        Console.WriteLine(new string('*', longestMessage));
                        break;
                    }
                }

            }
        }//done
        public static int FindLongestMassage(string[] messages)
        {
            var length = messages.Max(s => s.Length);
            return length;
        }//done

        private static void CreateNewCustomerAccount()
        {
            int attendedPerformancesCount = 0;
            string firstName;
            string lastName;
            string telephoneNumber;
            do
            {
                Console.WriteLine(new string('*', 159));
                Console.Write("Please enter custemer first name : ".PadRight(68,' '));
                firstName = Console.ReadLine();
            } while (String.IsNullOrEmpty(firstName) || isThereDigitInString(firstName));
            do
            {
                Console.Write("Please enter custemer lest name : ".PadRight(68, ' '));
                lastName = Console.ReadLine();
            } while (String.IsNullOrEmpty(lastName) || isThereDigitInString(lastName));


            Console.Write("Do you want to enter telephone number Y/N".PadRight(68, ' '));
            string customerAnswer = Console.ReadLine();
            Customer newCustemer;
            if (customerAnswer == "Y")
	        {
		      do
                {
                    Console.Write("Please enter your telephone number : ".PadRight(68, ' '));
                    telephoneNumber = Console.ReadLine();
                } while (String.IsNullOrEmpty(telephoneNumber));
                newCustemer = new RegularCustomer(attendedPerformancesCount, firstName, lastName, telephoneNumber);
	        }
            else
	        {
                newCustemer = new RegularCustomer(attendedPerformancesCount, firstName, lastName); 
	        }
            ourSystem.AddNewCustomer(newCustemer);
            Console.WriteLine(new string('*', 159));
        }

        static void CreateNewTicket()
        {
            string[] massages = 
            {
                "Please, enter the name of the seller: ",
                "Can't find this seller account. Press enter to go to the main menu or any number to try again: ",
                "Please, enter the name of the seller: ",
                "Please, enter the date and time of the performance:",
                "The date is not in correct format, please, press enter to exit or any number to try again.",
                "Please, enter the number of the play from the list: ",
                "Please, enter the row: ",
                "Do you want to enter a customer's name? Y/N",
                "Please, enter the customer's first name: ",
                "Please, enter the customer's last name: ",
                "The customer does not exist. Do you want to create a new customer's account: Y/N. Press 0 to go to the main menu. Press enter to try again.",
            };
           int longestMassage= FindLongestMassage(massages);
            string nameOfSeller;
            Play nameOfPlay;
            DateTime dateandTimeOfPerformance = new DateTime(1, 1, 1);
            Seat seatNumber;
            string firstNameOfCustomer = null;
            string lastNameOfCustomer = null;
            int choice = -1;
            Console.WriteLine(new string('*',159 ));//longestMassage+20
            Console.Write("Please, enter the name of the seller: ".PadRight(longestMassage,' '));
            nameOfSeller = Console.ReadLine();
            Seller currentSeller = ourSystem.ReturnSellerByName(nameOfSeller);
            while (currentSeller == null && choice != 0)
            {
               
                Console.Write("Can't find this seller account. Press enter to go to the main menu or any number to try again: ".PadRight(longestMassage,' '));
                Int32.TryParse(Console.ReadLine(), out choice);
                if (choice == 0)
                {
                    return;
                }
                Console.Write("Please, enter the name of the seller: ".PadRight(longestMassage, ' '));
                nameOfSeller = Console.ReadLine();
                currentSeller = ourSystem.ReturnSellerByName(nameOfSeller);
            }

            int choice2 = -1;
            while (dateandTimeOfPerformance == new DateTime(1, 1, 1) && choice != 0)
            {
                Console.Write("Please, enter the date and time of the performance:".PadRight(longestMassage, ' '));
                if (!DateTime.TryParse(Console.ReadLine(), out dateandTimeOfPerformance))
                {
                    Console.Write("The date is not in correct format, please, press enter to exit or any number to try again.".PadRight(longestMassage, ' '));
                    Int32.TryParse(Console.ReadLine(), out choice2);
                    if (choice2 == 0)
                    {
                        return;
                    }
                }
            }

            Console.Write("Please, enter the number of the play from the list: ".PadRight(longestMassage, ' '));
            int play = Int32.Parse(Console.ReadLine());
            nameOfPlay = (Play)play;

            Performance currentPerformance = ourSystem.ReturnPerformance(dateandTimeOfPerformance, nameOfPlay);

            bool choice3 = false;
            byte seatRow = 0;
            byte seatPlace = 0;
            while (!choice3)
            {
                Console.Write("Please, enter the row: ".PadRight(longestMassage, ' '));
                choice3 = Byte.TryParse(Console.ReadLine(), out seatRow);
                if (!choice3)
                {
                    continue;
                }

                Console.Write("Please, enter the col: ".PadRight(longestMassage, ' '));
                choice3 = Byte.TryParse(Console.ReadLine(), out seatPlace);
            }
            seatNumber = new Seat(seatRow, seatPlace);

            Ticket newticket;
            Console.Write("Do you want to enter a customer's name? Y/N".PadRight(longestMassage, ' '));
            if (Console.ReadLine() == "Y")
            {
                Customer currentCustomer = null;
                while (currentCustomer == null)
                {
                    Console.Write("Please, enter the customer's first name: ".PadRight(longestMassage, ' '));
                    firstNameOfCustomer = Console.ReadLine();
                    Console.Write("Please, enter the customer's last name: ".PadRight(longestMassage, ' '));
                    lastNameOfCustomer = Console.ReadLine();
                    currentCustomer = ourSystem.ReturnCustomerByName(firstNameOfCustomer + " " + lastNameOfCustomer);
                    if (currentCustomer == null)
                    {
                        Console.Write
                            ("The customer does not exist. Do you want to create a new customer's account: Y/N. Press 0 to go to the main menu. Press enter to try again."
                            .PadRight(longestMassage, ' '));
                        if (Console.ReadLine() == "Y")
                        {
                            CreateNewCustomerAccount();
                        }
                        if (Console.ReadLine() == "0")
                        {
                            return;
                        }
                    }
                }

                newticket = ourSystem.CreateNewTicket(currentCustomer, currentPerformance, seatNumber, currentSeller);
            }
            else
            {
                newticket = ourSystem.CreateNewTicket(currentPerformance, seatNumber, currentSeller);
            }

            Console.WriteLine(newticket.PrepareForPrint());
            Console.WriteLine(new string('*', 159));
            //TODO Test this one
        }

        static void CreateNewHall()
        {
            string nameOFhall;
            int rowsNumber;
            int colsNumber;
            Console.WriteLine("Enter the name of the new Hall!");
            nameOFhall = Console.ReadLine();
            int choiseRows = -1;
            int choiseCols = -1;
            bool isDigitRows = false;
            bool isDigitCols = false;
            while (choiseRows < 5 || !(isDigitRows))
            {
                Console.WriteLine("How many rows will your new Hall have,or press enter to return to Main menu?(At least 5 rows)");
                isDigitRows = int.TryParse(Console.ReadLine(), out choiseRows);
                if (isDigitRows && choiseRows > 4)
                {
                    while (choiseCols < 5 || !(isDigitCols))
                    {
                        Console.WriteLine("How many cols will your new Hall have,or press enter to return to Main menu?(At least 5 cols)");
                        isDigitCols = int.TryParse(Console.ReadLine(), out choiseCols);
                        if (isDigitCols && choiseCols > 4)
                        {
                            Hall newHall = new Hall(nameOFhall, CreateNewHallView(choiseRows, choiseCols));
                            Console.BackgroundColor = ConsoleColor.Red;
                            Console.WriteLine(newHall.PrepareForPrint());
                            ourSystem.AddNewHall(newHall);
                            Console.ResetColor();
                        }
                        else
                        {
                            Console.WriteLine("You haven't entered a number or your number is less than 5,try to enter a number again!");
                        }
                        if (choiseCols == 0)
                        {
                            return;
                        }
                    }

                }
                else
                {
                    Console.WriteLine("You haven't entered a number or your number is less than 5,try to enter a number again!");
                }
                if (choiseRows == 0)
                {
                    return;
                }
            }


        }

        static void CreateNewPerformance()
        {
            Console.WriteLine(new string('*', 159));
            Console.Write("Please, enter the date of the performance:".PadRight(68,' '));
            DateTime date;
            while (!DateTime.TryParse(Console.ReadLine(), out date))
            {
                Console.Write("Please, enter the date in the correct format.".PadRight(68, ' '));
            }

            Console.Write("Please, enter the number of the play:".PadRight(68, ' '));
            int playNumber = Int32.Parse(Console.ReadLine());
            Play play = (Play)playNumber;

            Console.Write("Please, enter the name of the Hall".PadRight(68, ' '));
            string nameOfHall = Console.ReadLine();
            Hall currentHall = ourSystem.ReturnHallByName(nameOfHall); ;
            string choice = "Y";
            while (currentHall == null && choice == "Y")
            {
                Console.Write("The hall was not found. Do you want to try again? Y/N".PadRight(68, ' '));
                choice = Console.ReadLine();
                if (choice != "Y")
                {
                    break;
                }
                Console.Write("Please, enter the name of the Hall".PadRight(68, ' '));
                currentHall = ourSystem.ReturnHallByName(nameOfHall);
            }

            Console.Write("Please, enter the price of the performance:".PadRight(68, ' '));
            int price; 
            while(!Int32.TryParse(Console.ReadLine(), out price))
            {
                Console.Write("Please, enter the price in the correct format.".PadRight(68, ' '));
            }
            
            ourSystem.AddNewPerformance(new Performance(currentHall, date, play, price));
            Console.WriteLine(new string('*', 159));
        }

        static void CreateNewSeller()
        {
            string sellerFirstName;
            string sellerLastName;
            string sellerSSN;
            Console.WriteLine(new string('*', 159));
            do
            {
                Console.Write("Please enter seller first name : ".PadRight(68,' '));
                sellerFirstName = Console.ReadLine();
            } while (String.IsNullOrEmpty(sellerFirstName) || isThereDigitInString(sellerFirstName));

            do
            {
                Console.Write("Please enter seller last name : ".PadRight(68, ' '));
                sellerLastName = Console.ReadLine();
            } while (String.IsNullOrEmpty(sellerLastName) || isThereDigitInString(sellerLastName));

            do
            {
                Console.Write("Please enter seller SSN : ".PadRight(68, ' '));
                sellerSSN = Console.ReadLine();
            } while (String.IsNullOrEmpty(sellerSSN) || isThereLetterInString(sellerSSN));

            Seller seller = new Seller(sellerFirstName, sellerLastName, sellerSSN);
            ourSystem.AddNewEmployee(seller);
            Console.WriteLine(new string('*', 159));
        }

        static bool isThereDigitInString(string inputString, bool isThereDigit = false)
        {
            foreach (char letter in inputString)
            {
                if (!Char.IsLetter(letter))
                {
                    isThereDigit = true;
                }
            }
            return isThereDigit;
        }

        static bool isThereLetterInString(string inputString)
        {
            foreach (char digit in inputString)
            {
                if (!Char.IsDigit(digit))
                {
                    return true;
                }
            }
            return false;
        }
        public static char[,] CreateNewHallView(int row, int col)
        {

            char[,] hallView = new char[row + 4, col + 4];
            #region insertElemenst
            for (int i = 0; i < row + 4; i++)
            {
                for (int j = 0; j < col + 4; j++)
                {
                    if (i == 0)
                    {
                        hallView[i, j] = '*';
                    }
                    else if (i == 1)
                    {
                        if (j == 0 || j == col + 3)
                        {
                            hallView[i, j] = '*';
                        }
                        else
                        {
                            hallView[i, j] = ' ';
                        }

                    }
                    else if (i == row + 2)
                    {
                        if (j == 0 || j == col + 3)
                        {
                            hallView[i, j] = '*';
                        }
                        else
                        {
                            hallView[i, j] = ' ';
                        }

                    }
                    else if (i == row + 3)
                    {
                        hallView[i, j] = '*';
                    }
                    else
                    {
                        if (j == 0 || j == col + 3)
                        {
                            hallView[i, j] = '*';
                        }
                        else if (j == 1 || j == col + 2)
                        {
                            hallView[i, j] = ' ';
                        }
                        else
                        {
                            hallView[i, j] = '=';
                        }
                    }
                }
            }
            #endregion
            return hallView;
        }

        public static void FindAllTicketsByCustomer()
        {
            //TODO implement this.
            Console.WriteLine(new string('*', 159));
            Console.Write("Enter the customer's name who's tickets you want to check.".PadRight(68, ' '));
            string customerName = Console.ReadLine();
            ICollection<Ticket> someTickets = new List<Ticket>(); 
            try 
	        {
	            someTickets = ourSystem.DictCustomerTicket[customerName];
            }
	        catch (Exception)
	        {
                Console.Write("The customer's name does not exist in the system".PadRight(68, ' '));
	        }

            foreach (Ticket ticket in someTickets)
            {
                Console.WriteLine(ticket.PrepareForPrint());
            }
            Console.WriteLine(new string('*', 159));
        }
        
        public static void FindAllTikecketsBySeller()
        {
            Console.WriteLine(new string('*', 159));
            Console.Write("Enter the seller's name who's tickets you want to check".PadRight(68,' '));
            string name = Console.ReadLine();
            ICollection<Ticket> someTickets=new List<Ticket>();
            try
            {
              someTickets = ourSystem.DictSellerTicket[name];
            }
            catch (Exception)
            {

                Console.Write("The seller's name does not exist in the system".PadRight(68, ' '));
            }
           

             
            foreach (var item in someTickets)
            {
                Console.WriteLine(item.PrepareForPrint());
            }
            Console.WriteLine(new string('*', 159));

        }
        public static void PrintTheHallViewOfPerpormance()
        {
            Console.WriteLine(new string('*', 159));
            int choice = -1;
            int choice2 = -1;
            DateTime dateandTimeOfPerformance = new DateTime(1, 1, 1);
            while (dateandTimeOfPerformance == new DateTime(1, 1, 1) && choice != 0)
            {
                Console.Write("Please, enter the date and time of the performance:".PadRight(68,' '));
                if (!DateTime.TryParse(Console.ReadLine(), out dateandTimeOfPerformance))
                {
                    Console.Write("The date is not in correct format, please, press enter to exit or any number to try again.".PadRight(148, ' '));
                    Int32.TryParse(Console.ReadLine(), out choice2);
                    if (choice2 == 0)
                    {
                        return;
                    }
                }
            }
            string[] str = Enum.GetNames(typeof(Play));
            int length = str.Length;
            int numberOfPlay = -1;
            bool isDigit = false;
            bool getOutOfLoop = false;
            Console.Write("Write the number of the play (a number from 0 to {0} including)!".PadRight(68,' '), length - 1);
            while (!(isDigit) || !getOutOfLoop)
            {
                isDigit = int.TryParse(Console.ReadLine(), out numberOfPlay);
                if (isDigit && numberOfPlay<length)
                {
                    Performance performance= ourSystem.ReturnPerformance(dateandTimeOfPerformance,(Play)numberOfPlay);
                    Console.WriteLine(performance.PrepareForPrint());
                    break;
                }
                else
                {
                    Console.Write("Your number is incorect ,write a number from 0 to {0} including)!".PadRight(68, ' '), length - 1);
                }
            }
            Console.WriteLine(new string('*', 159));
        }
    }

}
